package com.link.base.base.autoconfig.autoconfig.service.mysql;

import com.link.base.base.autoconfig.autoconfig.dao.mybatis.mapper.LnkInnerFieldMapper;
import com.link.base.base.autoconfig.autoconfig.dao.mybatis.mapper.LnkInnerLinkMapper;
import com.link.base.base.autoconfig.autoconfig.dao.mybatis.mapper.LnkInnerObjectMapper;
import com.link.base.base.autoconfig.autoconfig.dao.mybatis.mapper.LnkInnerWhereMapper;
import com.link.base.base.autoconfig.autoconfig.model.*;
import com.link.base.base.autoconfig.autoconfig.service.LnkInnerObjectService;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("lnkInnerObjectMySqlService")
public class LnkInnerObjectServiceMySqlImpl extends BasicServiceImpl<LnkInnerObject> implements LnkInnerObjectService {
    @Resource
    private LnkInnerObjectMapper lnkInnerObjectMapper;
    @Resource
    private LnkInnerFieldMapper lnkInnerFieldMapper;
    @Resource
    private LnkInnerLinkMapper lnkInnerLinkMapper;

    @Resource
    private LnkInnerWhereMapper lnkInnerWhereMapper;

    @Resource(name = "lnkInnerObjectService")
    private LnkInnerObjectService service;

    private static final Logger logger = LogManager.getLogger(LnkInnerObjectServiceMySqlImpl.class);

    @Override
    public BasicMapper<LnkInnerObject> getBasicMapper() {
        return lnkInnerObjectMapper;
    }

    @Override
    public String newQueryTable(LnkInnerObject record) throws Exception {
        Map<String, String> systemField = new HashMap<String, String>();
        systemField.put("id", "");
        systemField.put("created", "");
        systemField.put("created_by", "");
        systemField.put("last_upd", "");
        systemField.put("last_upd_by", "");
        systemField.put("orgId", "");
        systemField.put("postnId", "");
        String OutMsg = "";
        List<LnkInnerObject> headers = lnkInnerObjectMapper.queryByInner(record);
        for (LnkInnerObject header : headers) {
            Map<String, String> lineField = new HashMap<String, String>();
            OutMsg += "SELECT " + System.getProperty("line.separator");
            OutMsg += "     " + FormatStringToLength("T1.ROW_ID") + " as " + FormatStringToLength("id") + "/*记录ID*/"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("T1.CREATED")
                    + " as " + FormatStringToLength("created") + "/*创建时间*/"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("T1.CREATED_BY") + " as " + FormatStringToLength("createdBy")
                    + "/*创建者ID*/" + System.getProperty("line.separator");

            OutMsg += "    ," + FormatStringToLength("T1.LAST_UPD") + " as "
                    + FormatStringToLength("lastUpdated") + "/*最后更新时间*/" + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("T1.LAST_UPD_BY") + " as " + FormatStringToLength("lastUpdatedBy")
                    + "/*最后更新者ID*/" + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("T1.ORG_ID") + " as " + FormatStringToLength("orgId") + "/*组织ID*/"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("T1.POSTN_ID") + " as " + FormatStringToLength("postnId")
                    + "/*职位ID*/" + System.getProperty("line.separator");
            LnkInnerLink qps = new LnkInnerLink();
            qps.setParentid(record.getId());
            qps.setAttr02("Y");
            LnkInnerField qps1 = new LnkInnerField();
            qps1.setParentid(record.getId());
            qps1.setAttr02("Y");
            String whereString = "        WHERE 1=1" + System.getProperty("line.separator");
            List<LnkInnerLink> links = lnkInnerLinkMapper.queryByInner(qps);// query
            LnkInnerWhere lnkInnerWhere = new LnkInnerWhere();
            lnkInnerWhere.setParentid(record.getId());
            lnkInnerWhere.setAttr02("Y");
            List<LnkInnerWhere> lnkInnerWheres = lnkInnerWhereMapper.queryByInner(lnkInnerWhere);
            //兼容之前版本，取第一个from语句
            String LinkString;
            if (!lnkInnerWheres.isEmpty() && !StringUtils.isBlank(lnkInnerWheres.get(0).getLinkcoms())) {
                //兼容之前版本，取第一个from语句
                String fromSql = lnkInnerWheres.get(0).getLinkcoms();
                LinkString = fromSql + System.getProperty("line.separator") + whereString;
            } else {
                LinkString = "    FROM     " + FormatStringToLength(header.getBasetable()) + " "
                        + header.getBasetablealais() + System.getProperty("line.separator") + whereString;
            }
            // link
            List<LnkInnerField> fields = lnkInnerFieldMapper.queryByInner(qps1);// query
            // Field
            /* 处理基表的字段 */
            for (LnkInnerField field : fields) {
                if (field.getActiveflag() == null || "N".equals(field.getActiveflag())) {
                    continue;
                }
                if (field.getJoinname() != null && !"".equals(field.getJoinname())) {
                    continue;
                }
                if (field.getColumnname() == null || "".equals(field.getColumnname())) {
                    continue;
                }
                if (systemField.containsKey(field.getName())) {
                    continue;
                }
                if (lineField.containsKey(field.getName())) {
                    continue;
                }
                OutMsg += "    ," + FormatStringToLength("T1." + field.getColumnname()) + " as "
                        + FormatStringToLength(field.getName()) + "/*" + field.getDisplayname() + "*/"
                        + System.getProperty("line.separator");
                lineField.put(field.getName(), "");
            }
            for (LnkInnerLink link : links) {
                String linkname = link.getName();
                if (!"Y".equals(link.getAttr02())) {
                    continue;
                }
                LinkString += "        ," + FormatStringToLength(link.getTablename()) + " " + link.getAttr01()
                        + System.getProperty("line.separator");
                whereString += "        AND (" + link.getLinkcoms() + ")" + System.getProperty("line.separator");
                for (LnkInnerField field : fields) {
                    String fieldlinname = field.getJoinname();
                    if (field.getActiveflag() == null || "N".equals(field.getActiveflag())) {
                        continue;
                    }
                    //加这个条件是因为之前这里某些情况下会抛出空指针异常
                    if (null != linkname) {
                        if (!linkname.equals(fieldlinname) || fieldlinname == null || fieldlinname == "") {
                            continue;
                        }
                    }
                    if (systemField.containsKey(field.getName())) {
                        continue;
                    }
                    if (lineField.containsKey(field.getName())) {
                        continue;
                    }
                    OutMsg += "    ," + FormatStringToLength(link.getAttr01() + "." + field.getColumnname()) + " as "
                            + FormatStringToLength(field.getName()) + "/*" + field.getDisplayname() + "*/"
                            + System.getProperty("line.separator");
                    lineField.put(field.getName(), "");
                }
            }
            OutMsg += LinkString + System.getProperty("line.separator")
                    + System.getProperty("line.separator");
        }
//        LinkStatement linkStatement = new LinkStatement();
//        Map<String, String> transformResultMap = linkStatement.transformOracleQueryToMySql(OutMsg);
//        String sql = transformResultMap.get("sql");
        return OutMsg;
    }


    @Override
    public String newTable(LnkInnerObject record) throws Exception {
        Map<String, String> systemField = new HashMap<String, String>();
        systemField.put("ROW_ID", "");
        systemField.put("CREATED", "");
        systemField.put("CREATED_BY", "");
        systemField.put("LAST_UPD", "");
        systemField.put("LAST_UPD_BY", "");
        systemField.put("CORP_ID", "");
        systemField.put("ORG_ID", "");
        systemField.put("POSTN_ID", "");
        String OutMsg = "";
        LnkInnerObject qps = new LnkInnerObject();
        qps.setId(record.getId());
        qps.setAttr02("Y");
        List<LnkInnerObject> headers = lnkInnerObjectMapper.queryByInner(qps);
        for (LnkInnerObject header : headers) {
            Map<String, String> lineField = new HashMap<String, String>();
            //OutMsg += "-- DROP TABLE  IF EXISTS `" + header.getBasetable()
            // + "`;" + System.getProperty("line.separator");
            OutMsg += "CREATE TABLE IF NOT EXISTS `" + header.getBasetable()
                    + "` (" + System.getProperty("line.separator");
            OutMsg += "     " + FormatStringToLength("`ROW_ID`") + " "
                    + FormatStringToLength30("VARCHAR(30) NOT NULL") + "COMMENT '记录ID'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`CREATED`") + " "
                    + FormatStringToLength30("DATETIME DEFAULT NOW() NOT NULL") + "COMMENT '创建时间'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`CREATED_BY`") + " "
                    + FormatStringToLength30("VARCHAR(30) NOT NULL") + "COMMENT '创建者'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`LAST_UPD`") + " "
                    + FormatStringToLength30("DATETIME DEFAULT NOW() NOT NULL") + "COMMENT '最后更新时间'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`LAST_UPD_BY`") + " "
                    + FormatStringToLength30("VARCHAR(30) NOT NULL") + "COMMENT '最后更新者'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`CORP_ID`") + " " + FormatStringToLength30("VARCHAR(5)")
                    + "COMMENT '公司账套ID'" + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`ORG_ID`") + " "
                    + FormatStringToLength30("VARCHAR(30)") + "COMMENT '组织ID'"
                    + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`POSTN_ID`") + " " + FormatStringToLength30("VARCHAR(30)")
                    + "COMMENT '职位ID'" + System.getProperty("line.separator");
            OutMsg += "    ," + FormatStringToLength("`ROW_VERSION`") + " "
                    + FormatStringToLength30("BIGINT(19) NOT NULL DEFAULT 1 ") + "COMMENT '版本号'"
                    + System.getProperty("line.separator");
            String IndexString = "";
//            String IndexString = "ALTER TABLE `" + header.getBasetable()
//                    + "` ADD PRIMARY KEY (`ROW_ID`);" + System.getProperty("line.separator");
            int indexcountU = 1;
            int indexcountN = 1;
            String AddcolString = "/* 以下脚本为在现有表中增加字段的脚本，请在MySQL的命令行中执行*/"
                    + System.getProperty("line.separator") + "/*" + System.getProperty("line.separator");
            AddcolString += "ALTER TABLE `" + header.getBasetable() + "` ADD COLUMN "
                    + FormatStringToLength("`CORP_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(5);") + System.getProperty("line.separator");
            AddcolString += "ALTER TABLE `" + header.getBasetable() + "` ADD COLUMN "
                    + FormatStringToLength("`ORG_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(30);") + System.getProperty("line.separator");
            AddcolString += "ALTER TABLE `" + header.getBasetable() + "` ADD COLUMN "
                    + FormatStringToLength("`POSTN_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(30);") + System.getProperty("line.separator");
            String ModifyString = "/* 以下脚本为在现有表中修改字段的脚本，请在MySQL的命令行中执行*/"
                    + System.getProperty("line.separator") + "/*" + System.getProperty("line.separator");
            ModifyString += "ALTER TABLE `" + header.getBasetable() + "` CHANGE COLUMN "
                    + FormatStringToLength("`CORP_ID`") + " " + FormatStringToLength("`CORP_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(5);") + System.getProperty("line.separator");
            ModifyString += "ALTER TABLE `" + header.getBasetable() + "` CHANGE COLUMN "
                    + FormatStringToLength("`ORG_ID`") + " " + FormatStringToLength("`ORG_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(30);") + System.getProperty("line.separator");
            ModifyString += "ALTER TABLE `" + header.getBasetable() + "` CHANGE COLUMN "
                    + FormatStringToLength("`POSTN_ID`") + " " + FormatStringToLength("`POSTN_ID`") + " "
                    + FormatStringToLength30("VARCHAR2(30);") + System.getProperty("line.separator");
            LnkInnerField qps1 = new LnkInnerField();
            qps1.setParentid(record.getId());
            List<LnkInnerField> fields = lnkInnerFieldMapper.queryByInner(qps1);
            String LastCreatedString = header.getCreated(10).substring(0, 10);
            String LastCreatedByName = header.getCreatedByName();
            for (LnkInnerField field : fields) {
                String CreatedByInfo = "";
                String CreatedString = field.getCreated(10).substring(0, 10);
                if (!LastCreatedString.equals(CreatedString)) {
                    LastCreatedString = CreatedString;
                    CreatedByInfo = System.getProperty("line.separator") + "    /*created:"
                            + CreatedString + ",createdBy:" + field.getCreatedByName() + "*/"
                            + System.getProperty("line.separator");
                }
                if (!LastCreatedByName.equals(field.getCreatedByName())) {
                    LastCreatedByName = field.getCreatedByName();
                    CreatedByInfo = System.getProperty("line.separator") + "    /*created:"
                            + CreatedString + ",createdBy:" + field.getCreatedByName() + "*/"
                            + System.getProperty("line.separator");
                }

                if (field.getActiveflag() == null || "N".equals(field.getActiveflag())) {
                    logger.info("field.getActiveflag() is:");
                    logger.info(field.getActiveflag());
                    continue;
                }
                if ("Y".equals(field.getCalc())) {
                    logger.info("field.getCalc() is:");
                    logger.info(field.getActiveflag());
                    continue;
                }
                if (field.getJoinname() != null && !"".equals(field.getJoinname())) {
                    logger.info("field.getJoinname() is:");
                    logger.info(field.getJoinname());
                    continue;
                }
                if (field.getColumnname() == null || "".equals(field.getColumnname())) {
                    logger.info("getColumnname field is blank!");
                    logger.info(field.getDisplayname());
                    continue;
                }
                if (systemField.containsKey(field.getColumnname())) {
                    logger.info("getColumnname is system field:");
                    logger.info(field.getColumnname());
                    continue;
                }
                if (lineField.containsKey(field.getColumnname())) {
                    logger.info("getColumnname field is aleady exists!");
                    logger.info(field.getColumnname());
                    continue;
                }
                String FieldType = "";
                if ("VARCHAR2".equals(field.getColumntype())) {
                    FieldType = "VARCHAR(" + field.getColumnlength() + ")";
                } else if ("NUMBER".equals(field.getColumntype())) {
                    FieldType = "DECIMAL(22,7)";
                } else if ("DATE".equals(field.getColumntype())) {
                    FieldType = "DATETIME";
                } else if ("CLOB".equals(field.getColumntype())) {
                    FieldType = "TEXT";
                } else if ("CHAR".equals(field.getColumntype())) {
                    FieldType = "CHAR(" + field.getColumnlength() + ")";
                } else if ("BIGINT".equals(field.getColumntype())) {
                    FieldType = "BIGINT(" + field.getColumnlength() + ")";
                }
                OutMsg += "    ," + FormatStringToLength("`" + field.getColumnname() + "`") + " " + FormatStringToLength30(FieldType)
                        + "COMMENT '" + field.getDisplayname() + "' "
                        + System.getProperty("line.separator");
                lineField.put(field.getColumnname(), "");
                if ("Normal".equals(field.getIndextype())) {
                    /*IndexString += "CREATE INDEX " + header.getBasetable() + "_N" + indexcountN
                            + " ON "
                            + header.getBasetable() + " (" + field.getColumnname() + ");"
                            + System.getProperty("line.separator");*/


                    IndexString += FormatStringToLength30( "    ,INDEX `" + header.getBasetable() + "_N" + indexcountN + "`")
                            + FormatStringToLength(" (`" + field.getColumnname() + "`)")
                            + "USING BTREE"
                            + System.getProperty("line.separator");

//                    IndexString += "ALTER TABLE `" + header.getBasetable() + "` ADD INDEX `"
//                            + header.getBasetable() + "_N" + indexcountN
//                            + "` (`" + field.getColumnname() + "`);"
//                            + System.getProperty("line.separator");
                    indexcountN++;
                } else if ("Unique".equals(field.getIndextype())) {
                    IndexString += FormatStringToLength30( "    ,UNIQUE INDEX `" + header.getBasetable() + "_U" + indexcountU + "`")
                            + FormatStringToLength(" (`" + field.getColumnname() + "`)")
                            + "USING BTREE"
                            + System.getProperty("line.separator");
//                    IndexString += "ALTER TABLE `" + header.getBasetable() + "` ADD UNIQUE INDEX `"
//                            + header.getBasetable() + "_U" + indexcountU
//                            + "` (`" + field.getColumnname() + "`);"
//                            + System.getProperty("line.separator");
                    indexcountU++;
                }
                if (!"".equals(CreatedByInfo)) {
                    AddcolString += CreatedByInfo;
                    ModifyString += CreatedByInfo;

                }
                AddcolString += "ALTER TABLE `" + header.getBasetable() + "` ADD COLUMN "
                        + FormatStringToLength("`" + field.getColumnname() + "`")
                        + FormatStringToLength30(FieldType + ";")
                        + System.getProperty("line.separator");
                ModifyString += "ALTER TABLE `" + header.getBasetable() + "` CHANGE COLUMN "
                        + FormatStringToLength("`" + field.getColumnname() + "`")
                        + FormatStringToLength("`" + field.getColumnname() + "`")
                        + FormatStringToLength30(FieldType + ";")
                        + System.getProperty("line.separator");
            }
            OutMsg += "    ,PRIMARY KEY (`ROW_ID`) " + System.getProperty("line.separator")
                    + IndexString + ") COMMENT='" + header.getAttr01() + "';" + System.getProperty("line.separator")
                    + System.getProperty("line.separator");
            //OutMsg += commentString + System.getProperty("line.separator") + System.getProperty("line.separator");
            OutMsg += System.getProperty("line.separator") + System.getProperty("line.separator")
                    + AddcolString + "*/" + System.getProperty("line.separator");
            OutMsg += ModifyString + "*/" + System.getProperty("line.separator");
        }
        return OutMsg;
    }

    /**
     * <p>格式化字符串，null返回"" ; 长度不足20用空格补偿</p>
     *
     * @param sChar
     * @return
     */
    private String FormatStringToLength(String sChar) {
        if (sChar == null) {
            return "";
        }
        while (sChar.length() < 20) {
            sChar += " ";
        }
        return sChar;
    }

    /**
     * <p>格式化字符串，null返回"" ; 长度不足34用空格补偿</p>
     *
     * @param sChar
     * @return
     */
    private String FormatStringToLength30(String sChar) {
        if (sChar == null) {
            return "";
        }
        while (sChar.length() < 34) {
            sChar += " ";
        }
        return sChar;
    }

    @Override
    public Map<String, String> newObjectFile(LnkInnerObject record) throws Exception {
        return service.newObjectFile(record);
    }

    @Override
    public List<FileExport> newObjectFile(Long id) throws Exception {
        return service.newObjectFile(id);
    }

    @Override
    public String Check(LnkInnerObject record) throws Exception {
        return service.Check(record);
    }

    @Override
    public void DeepCopy(LnkInnerObject record) throws Exception {
        service.DeepCopy(record);
    }

    @Override
    public void getmodelinfo(LnkInnerObject record) throws Exception {
        service.getmodelinfo(record);
    }

    @Override
    public void updatemodelinfo(LnkInnerObject record) throws Exception {
        service.updatemodelinfo(record);
    }

    @Override
    public LnkInnerObject getFullLnkInnerObjectById(LnkInnerObject record) throws Exception {
        return service.getFullLnkInnerObjectById(record);
    }

    @Override
    public String test(LnkInnerObject record) throws Exception {
        // TODO Auto-generated method stub
        return service.test(record);
    }

    @Override
    public String newSqlMapper(LnkInnerObject record, String dataBaseType, boolean genIfTestTag) throws Exception {
        // TODO Auto-generated method stub
        return service.newSqlMapper(record, dataBaseType, genIfTestTag);
    }

    @Override
    public void deployIdUpdate(Long id, Long deployId) {
        service.deployIdUpdate(id, deployId);
    }
}
